home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gdb / gdb_18s.zoo / expprint.c < prev    next >
C/C++ Source or Header  |  1992-03-25  |  10KB  |  305 lines

  1. /* Print in infix form a struct expression.
  2.    Copyright (C) 1986 Free Software Foundation, Inc.
  3.  
  4. GDB is distributed in the hope that it will be useful, but WITHOUT ANY
  5. WARRANTY.  No author or distributor accepts responsibility to anyone
  6. for the consequences of using it or for whether it serves any
  7. particular purpose or works at all, unless he says so in writing.
  8. Refer to the GDB General Public License for full details.
  9.  
  10. Everyone is granted permission to copy, modify and redistribute GDB,
  11. but only under the conditions described in the GDB General Public
  12. License.  A copy of this license is supposed to have been given to you
  13. along with GDB so you can know your rights and responsibilities.  It
  14. should be in a file named COPYING.  Among other things, the copyright
  15. notice and this notice must be preserved on all copies.
  16.  
  17. In other words, go ahead and share GDB, but don't try to stop
  18. anyone else from sharing it farther.  Help stamp out software hoarding!
  19. */
  20.  
  21. #include "defs.h"
  22. #include "symtab.h"
  23. #include "expression.h"
  24.  
  25. #include <stdio.h>
  26.  
  27. /* These codes indicate operator precedences, least tightly binding first.  */
  28. /* Adding 1 to a precedence value is done for binary operators,
  29.    on the operand which is more tightly bound, so that operators
  30.    of equal precedence within that operand will get parentheses.  */
  31. /* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
  32.    they are used as the "surrounding precedence" to force
  33.    various kinds of things to be parenthesized.  */
  34. enum precedence
  35. { PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_OR, PREC_AND,
  36.   PREC_LOGIOR, PREC_LOGAND, PREC_LOGXOR, PREC_EQUAL, PREC_ORDER,
  37.   PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT,
  38.   PREC_HYPER, PREC_PREFIX, PREC_SUFFIX };
  39.  
  40. /* Table mapping opcodes into strings for printing operators
  41.    and precedences of the operators.  */
  42.  
  43. struct op_print
  44. {
  45.   char *string;
  46.   enum exp_opcode opcode;
  47.   /* Precedence of operator.  These values are used only by comparisons.  */
  48.   enum precedence precedence;
  49.   int right_assoc;
  50. };
  51.  
  52. static struct op_print op_print_tab[] =
  53.   {
  54.     {",", BINOP_COMMA, PREC_COMMA, 0},
  55.     {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
  56.     {"||", BINOP_OR, PREC_OR, 0},
  57.     {"&&", BINOP_AND, PREC_AND, 0},
  58.     {"|", BINOP_LOGIOR, PREC_LOGIOR, 0},
  59.     {"&", BINOP_LOGAND, PREC_LOGAND, 0},
  60.     {"^", BINOP_LOGXOR, PREC_LOGXOR, 0},
  61.     {"==", BINOP_EQUAL, PREC_EQUAL, 0},
  62.     {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
  63.     {"<=", BINOP_LEQ, PREC_ORDER, 0},
  64.     {">=", BINOP_GEQ, PREC_ORDER, 0},
  65.     {">", BINOP_GTR, PREC_ORDER, 0},
  66.     {"<", BINOP_LESS, PREC_ORDER, 0},
  67.     {">>", BINOP_RSH, PREC_SHIFT, 0},
  68.     {"<<", BINOP_LSH, PREC_SHIFT, 0},
  69.     {"+", BINOP_ADD, PREC_ADD, 0},
  70.     {"-", BINOP_SUB, PREC_ADD, 0},
  71.     {"*", BINOP_MUL, PREC_MUL, 0},
  72.     {"/", BINOP_DIV, PREC_MUL, 0},
  73.     {"%", BINOP_REM, PREC_MUL, 0},
  74.     {"@", BINOP_REPEAT, PREC_REPEAT, 0},
  75.     {"-", UNOP_NEG, PREC_PREFIX, 0},
  76.     {"!", UNOP_ZEROP, PREC_PREFIX, 0},
  77.     {"~", UNOP_LOGNOT, PREC_PREFIX, 0},
  78.     {"*", UNOP_IND, PREC_PREFIX, 0},
  79.     {"&", UNOP_ADDR, PREC_PREFIX, 0},
  80.     {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
  81.     {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
  82.     {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}
  83.   };
  84.  
  85. static void print_subexp ();
  86.  
  87. void
  88. print_expression (exp, stream)
  89.      struct expression *exp;
  90.      FILE *stream;
  91. {
  92.   int pc = 0;
  93.   print_subexp (exp, &pc, stream, PREC_NULL);
  94. }
  95.  
  96. /* Print the subexpression of EXP that starts in position POS, on STREAM.
  97.    PREC is the precedence of the surrounding operator;
  98.    if the precedence of the main operator of this subexpression is less,
  99.    parentheses are needed here.  */
  100.  
  101. static void
  102. print_subexp (exp, pos, stream, prec)
  103.      register struct expression *exp;
  104.      register int *pos;
  105.      FILE *stream;
  106.      enum precedence prec;
  107. {
  108.   register int tem;
  109.   register int pc;
  110.   int nargs;
  111.   register char *op_str;
  112.   int assign_modify = 0;
  113.   enum exp_opcode opcode;
  114.   enum precedence myprec;
  115.   /* Set to 1 for a right-associative operator.  */
  116.   int assoc;
  117.  
  118.   pc = (*pos)++;
  119.   opcode = exp->elts[pc].opcode;
  120.   switch (opcode)
  121.     {
  122.     case OP_LONG:
  123.       (*pos) += 3;
  124.       value_print (value_from_long (exp->elts[pc + 1].type,
  125.                     exp->elts[pc + 2].longconst),
  126.            stream, 0);
  127.       return;
  128.  
  129.     case OP_DOUBLE:
  130.       (*pos) += 3;
  131.       value_print (value_from_double (exp->elts[pc + 1].type,
  132.                       exp->elts[pc + 2].doubleconst),
  133.            stream, 0);
  134.       return;
  135.  
  136.     case OP_VAR_VALUE:
  137.       (*pos) += 2;
  138.       fprintf_filtered (stream, "%s", SYMBOL_NAME (exp->elts[pc + 1].symbol));
  139.       return;
  140.  
  141.     case OP_LAST:
  142.       (*pos) += 2;
  143.       fprintf_filtered (stream, "$%d", exp->elts[pc + 1].longconst);
  144.       return;
  145.  
  146.     case OP_REGISTER:
  147.       (*pos) += 2;
  148.       fprintf_filtered (stream, "$%s", reg_names[exp->elts[pc + 1].longconst]);
  149.       return;
  150.  
  151.     case OP_INTERNALVAR:
  152.       (*pos) += 2;
  153.       fprintf_filtered (stream, "$%s",
  154.            internalvar_name (exp->elts[pc + 1].internalvar));
  155.       return;
  156.  
  157.     case OP_FUNCALL:
  158.       (*pos) += 2;
  159.       nargs = exp->elts[pc + 1].longconst;
  160.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  161.       fprintf_filtered (stream, " (");
  162.       for (tem = 0; tem < nargs; tem++)
  163.     {
  164.       if (tem != 0)
  165.         fprintf_filtered (stream, ", ");
  166.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  167.     }
  168.       fprintf_filtered (stream, ")");
  169.       return;
  170.  
  171.     case OP_STRING:
  172.       nargs = strlen (&exp->elts[pc + 1].string);
  173.       (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  174.       fprintf_filtered (stream, "\"");
  175.       for (tem = 0; tem < nargs; tem++)
  176.     printchar ((&exp->elts[pc + 1].string)[tem], stream);
  177.       fprintf_filtered (stream, "\"");
  178.       return;
  179.  
  180.     case TERNOP_COND:
  181.       if ((int) prec > (int) PREC_COMMA)
  182.     fprintf_filtered (stream, "(");
  183.       /* Print the subexpressions, forcing parentheses
  184.      around any binary operations within them.
  185.      This is more parentheses than are strictly necessary,
  186.      but it looks clearer.  */
  187.       print_subexp (exp, pos, stream, PREC_HYPER);
  188.       fprintf_filtered (stream, " ? ");
  189.       print_subexp (exp, pos, stream, PREC_HYPER);
  190.       fprintf_filtered (stream, " : ");
  191.       print_subexp (exp, pos, stream, PREC_HYPER);
  192.       if ((int) prec > (int) PREC_COMMA)
  193.     fprintf_filtered (stream, ")");
  194.       return;
  195.  
  196.     case STRUCTOP_STRUCT:
  197.       tem = strlen (&exp->elts[pc + 1].string);
  198.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  199.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  200.       fprintf_filtered (stream, ".%s", &exp->elts[pc + 1].string);
  201.       return;
  202.  
  203.     case STRUCTOP_PTR:
  204.       tem = strlen (&exp->elts[pc + 1].string);
  205.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  206.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  207.       fprintf_filtered (stream, "->%s", &exp->elts[pc + 1].string);
  208.       return;
  209.  
  210.     case BINOP_SUBSCRIPT:
  211.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  212.       fprintf_filtered (stream, "[");
  213.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  214.       fprintf_filtered (stream, "]");
  215.       return;
  216.  
  217.     case UNOP_POSTINCREMENT:
  218.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  219.       fprintf_filtered (stream, "++");
  220.       return;
  221.  
  222.     case UNOP_POSTDECREMENT:
  223.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  224.       fprintf_filtered (stream, "--");
  225.       return;
  226.  
  227.     case UNOP_CAST:
  228.       (*pos) += 2;
  229.       if ((int) prec > (int) PREC_PREFIX)
  230.     fprintf_filtered (stream, "(");
  231.       fprintf_filtered (stream, "(");
  232.       type_print (exp->elts[pc + 1].type, "", stream, 0);
  233.       fprintf_filtered (stream, ") ");
  234.       print_subexp (exp, pos, stream, PREC_PREFIX);
  235.       if ((int) prec > (int) PREC_PREFIX)
  236.     fprintf_filtered (stream, ")");
  237.       return;
  238.  
  239.     case UNOP_MEMVAL:
  240.       (*pos) += 2;
  241.       if ((int) prec > (int) PREC_PREFIX)
  242.     fprintf_filtered (stream, "(");
  243.       fprintf_filtered (stream, "{");
  244.       type_print (exp->elts[pc + 1].type, "", stream, 0);
  245.       fprintf_filtered (stream, "} ");
  246.       print_subexp (exp, pos, stream, PREC_PREFIX);
  247.       if ((int) prec > (int) PREC_PREFIX)
  248.     fprintf_filtered (stream, ")");
  249.       return;
  250.  
  251.     ca